Skip to content

autodiff: AD-OPERATOR-1 — operator tangents + the H3 well-posedness certificate - #597

Merged
gstoner merged 1 commit into
mainfrom
agent/ad-operator-1
Aug 21, 2026
Merged

gstoner merged 1 commit into
mainfrom
agent/ad-operator-1

Conversation

@gstoner

@gstoner gstoner commented Aug 20, 2026

Copy link
Copy Markdown
Owner

AD-OPERATOR-1 — operator tangents + the H3 well-posedness certificate

The next AUTODIFF_NEXTGEN slice (§7, ~2w item, independent of the jet lane). One commit, three pieces:

OperatorTangent (autodiff/operator.py)

implicit.py's local matvec pattern promoted to a type (plan §3.5): a matrix-free linear map with composition as the operator product, .T as an involution, and solve-consumption — instances are callable, so cg_solve/gmres_solve take an operator anywhere they took a bare closure. A forward-only operator refuses .T rather than silently finite-differencing an adjoint. The Decision #31 relationship to the materialized @f__bwd ABI (one production lowering, one declared unmaterialized twin) is recorded in the module docstring, next to the type.

implicit.py refactored, behavior-identical

ihvp (declared-self-adjoint Hessian operator into CG), root_vjp (the (−Bᵀ)∘A⁻ᵀ chain through the type's own transpose), root_jvp, adjoint_state_grad, and the dense oracle via operator.materialize(). All 54 pre-existing implicit/solver-IFT tests pass unchanged — they are the regression net the plan names.

H3: the strict-complementarity / well-posedness certificate

CORE_SUBSTRATE_VIEW.md S8's previously unowned "one fix, three consumers" item (game theory, Riemannian-OT, S-series). certify_root measures the IFT hypothesis at a claimed root instead of assuming it: the point is actually a root (scaled residual tolerance) and ∂ₓF is non-degenerate (σ_min > tol·σ_max — for KKT-form residuals, exactly what strict complementarity guarantees). custom_root gates differentiation on it by default, in both the convenience methods and the tape path:

  • a degenerate root rejects with the measured numbers (σ_min/σ_max/condition) instead of returning an ill-posed gradient;
  • a non-root rejects on the residual;
  • an unevaluable check fails closed (non-finite residual/Jacobian is an error, never a pass);
  • certify=False is an explicit opt-out, and solver.certificate(x*, params) exposes the record itself (S4: numbers, not booleans).

Acceptance (tests/unit/test_operator_tangent.py, 13 tests)

Operator-level adjoint law ⟨Av,u⟩=⟨v,Aᵀu⟩ through the type's own transpose including a falsifiability control (an operator with a wrong declared adjoint fails the pairing); involution + (AB)ᵀ = BᵀAᵀ; fail-closed edges; solve consumption; certificate positive/negative fixtures (clean √θ root with measured σ_min = 2√2; degenerate x²−θ at θ=0; singular 2×2 system); tape-backward rejection at a degenerate root.

Gauss–Newton / Newton–Krylov compositions are the named future consumers — no such op exists in-tree yet, and inventing one would be Decision #29 in reverse.

Verification (Strix Halo box)

27 implicit+operator tests, 571-test autodiff regression net, ruff + mypy clean, generated docs in sync. Full CI-equivalent suite: 16,161 pass; the failing set is file-for-file the known pre-existing environmental baseline (Apple-lane tests vs this box's non-Apple tessera-opt, which CI skips + the pre-existing gfx1151 provenance assert), with the two known xdist-flaky dashboard tests re-verified green in isolation.

🤖 Generated with Claude Code

…ertificate

OperatorTangent (autodiff/operator.py) promotes implicit.py's local
matvec pattern to a type: a matrix-free linear map with composition as
the operator product, .T as an involution, and solve-consumption —
instances are callable, so cg_solve/gmres_solve take an operator
anywhere they took a bare closure. A forward-only operator REFUSES .T
rather than silently finite-differencing an adjoint. The Decision #31
relationship to the materialized @f__bwd ABI (one production lowering,
one declared unmaterialized twin) is recorded in the module docstring.

implicit.py is refactored onto the type behavior-identically:
ihvp (declared-self-adjoint Hessian operator into CG), root_vjp
(A.T solve, parameter pullback -(B.T @ r) — the (−Bᵀ)∘A⁻ᵀ chain),
root_jvp, adjoint_state_grad (∂₁cᵀ through the type's transpose), and
the dense oracle through operator.materialize(). All 54 pre-existing
implicit/solver-IFT tests pass unchanged.

H3 (CORE_SUBSTRATE_VIEW S8, the previously unowned one-fix-three-
consumers item): certify_root measures the IFT hypothesis at a claimed
root instead of assuming it — residual within tolerance AND
σ_min > tol·σ_max of ∂ₓF (for KKT residuals, the strict-complementarity
condition). custom_root gates differentiation on it by default in both
convenience methods and the tape path: a degenerate root rejects with
the measured numbers, a non-root rejects on the residual, an unevaluable
check fails closed, and certify=False is an explicit opt-out. The
certificate itself is exposed (solver.certificate) in the S4
numbers-not-booleans discipline.

Acceptance (tests/unit/test_operator_tangent.py, 13 tests): the
operator-level adjoint law incl. a falsifiability control (a wrong
adjoint fails the pairing), transpose involution + (AB)ᵀ = BᵀAᵀ,
fail-closed edges, solve consumption, certificate positive/negative
fixtures, and tape-backward rejection at a degenerate root.

Gauss–Newton / Newton–Krylov compositions are the named future
consumers; no such op exists in-tree yet and inventing one would be
Decision #29 in reverse.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06bb92fa96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread python/tessera/autodiff/operator.py
Comment thread python/tessera/autodiff/operator.py
@gstoner

gstoner commented Aug 21, 2026

Copy link
Copy Markdown
Owner Author

Both review findings were real — reproduced exactly as described (wide Jacobian: svals=[√2], strict=True; zero Jacobian: condition=0.0). Since this PR merged first, the fixes landed as follow-up #599: certify_root now fails closed on any non-square residual Jacobian (wide = free direction, not locally unique; tall = least-squares, not an IFT root — the thin-SVD null-space blindness can no longer certify anything), and a singular Jacobian reports κ = ∞ instead of 0. Both pinned with the exact fixtures from the review. One mitigating note for the record: root_vjp/root_jvp already required square systems, so no wrong gradient could escape end-to-end — the certificate itself was the confidently-wrong surface.

@gstoner
gstoner deleted the agent/ad-operator-1 branch August 21, 2026 00:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant